package internal

import (
	"context"
	"time"
)

type RocketProxy interface {
	CreateConsumer(topicName, groupID, messageTag string) (MQConsumer, error)
	CreateTransProducer(topicName, groupID string) (MQTransProducer, error)
	PublishMessage(topicName, messageBody string) error
	PublishMsgWithTag(topicName, messageBody, messageTag string) error
	PublishMsgWithKeyTag(topicName, messageBody, messageTag, messageKey string) error
	PublishDelayMessage(topicName, messageBody string, delay time.Duration) error
	PublishDelayMsgWithTag(topicName, messageBody, messageTag string, delay time.Duration) error
	PublishDelayMsgWithKeyTag(topicName, messageBody, messageTag, messageKey string, delay time.Duration) error
	PublishMessageProp(topicName, messageTag, messageBody string, properties map[string]string) error
	PublishDelayMessageProt(topicName, messageBody string, properties map[string]string, delay time.Duration) error
	RegisterListener(topicName string, listener TransactionListener)
	PublishMsgWithTagTrans(topicName, groupID, messageBody, messageTag string, properties map[string]string) (*ConsumeMessageAck, error)
	PublishWithCommit(topicName, groupID, handler string) error
	PublishWithRollBack(topicName, groupID, handler string) error
}

type MQTransProducer interface {
	// PublishMessage 发送消息
	PublishMessage(message PublishMessageRequest) (resp PublishMessageResponse, err error)
	// ConsumeHalfMessage 消费事务半消息
	ConsumeHalfMessage(respChan chan ConsumeMessageResponse, errChan chan error, numOfMessages int32, waitseconds int64)
	// Commit 提交事务消息
	Commit(receiptHandle string) (err error)
	// Rollback 回滚事务消息
	Rollback(receiptHandle string) (err error)

	// Start apache
	Start() error
	// Shutdown apache producer
	Shutdown() error
	// SendMessageInTransaction apache producer
	SendMessageInTransaction(ctx context.Context, mq *Message) (*TransactionSendResult, error)
}

type MQConsumer interface {
	// TopicName 获取TopicName
	TopicName() string
	// MessageTag 获取MessageTag
	MessageTag() string
	// ConsumeMessage 消费消息，如果该条消息没有被 {AckMessage} 确认消费成功，即在NextConsumeTime时会再次消费到该条消息
	ConsumeMessage(respChan chan ConsumeMessageResponse, errChan chan error, numOfMessages int32, waitseconds int64)
	// ConsumeMessageOrderly 顺序消费消息，获取的消息可能是多个分区但是一个分区内消息一定是顺序的，对于一个分区的消息必须要全部ACK成功才能消费下一批消息
	// 否则在NextConsumeTime后会再次消费到相同的消息
	ConsumeMessageOrderly(respChan chan ConsumeMessageResponse, errChan chan error, numOfMessages int32, waitseconds int64)
	// AckMessage 确认消息消费成功
	AckMessage(receiptHandles []string) (err error)
	// Start the PushConsumer for consuming message
	Start() error
	// Subscribe a topic for consuming
	Subscribe(topic string, selector MessageSelector,
		f func(context.Context, ...*MessageExt) (ConsumeResult, error)) error
	// Unsubscribe a topic
	Unsubscribe(topic string) error
}
